package hello;

/**
 * Created with IntelliJIDEA.
 * Description:
 * User: ASUS
 * Date: 2025/9/11
 * Time: 21:32
 */

public class StringCompareDemo {
    public static void main(String[] args) {
        // 场景1：两个字面量
        String s1 = "Java"; // 在常量池中创建 "Java"
        String s2 = "Java"; // 常量池中已存在 "Java"，直接返回其引用
        System.out.println("s1 == s2: " + (s1 == s2));       // true, 因为都指向常量池中的同一个对象
        System.out.println("s1.equals(s2): " + s1.equals(s2)); // true, 因为内容相同

        System.out.println("-----------");

        // 场景2：字面量与 new 对象
        String s3 = new String("Java"); // 在堆中创建一个新对象，其内容为 "Java"
        System.out.println("s1 == s3: " + (s1 == s3));       // false, s1在常量池，s3在堆，地址不同
        System.out.println("s1.equals(s3): " + s1.equals(s3)); // true, 内容相同

        System.out.println("-----------");

        // 场景3：两个 new 对象
        String s4 = new String("Java"); // 在堆中又创建了一个新对象
        System.out.println("s3 == s4: " + (s3 == s4));       // false, s3和s4是堆中两个独立的对象，地址不同
        System.out.println("s3.equals(s4): " + s3.equals(s4)); // true, 内容相同

        System.out.println("-----------");

        // 场景4：字符串拼接
        String s5 = "Ja";
        String s6 = "va";
        String s7 = s5 + s6; // 编译期无法确定s7的值，所以会在运行时 new 一个StringBuilder来拼接，最后返回一个堆上的新String对象
        System.out.println("s1 == s7: " + (s1 == s7));       // false, s1在常量池, s7在堆
        System.out.println("s1.equals(s7): " + s1.equals(s7)); // true, 内容相同

        // 场景5：常量拼接
        final String s8 = "Ja";
        final String s9 = "va";
        String s10 = s8 + s9; // s8和s9是常量，编译器在编译期就能确定s10的值是 "Java"，会直接优化为 String s10 = "Java";
        System.out.println("s1 == s10: " + (s1 == s10));    // true, 编译器优化，s10直接指向常量池

        String s11 = "Ja" + "va"; // 字面量拼接，编译器直接优化
        System.out.println("s1 == s11: " + (s1 == s11));    // true, 同上

        System.out.println("-----------");

        // 场景6: 使用 intern()
        String s12 = new String("Java").intern(); // s12 是堆中对象调用intern()后的返回值，即常量池中的 "Java" 的引用
        System.out.println("s1 == s12: " + (s1 == s12));    // true, 因为s12现在也指向常量池
    }
}






